package com.example.config.shiro;


import com.example.util.shiro.RedisUtil;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.mgt.RealmSecurityManager;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.subject.support.DefaultSubjectContext;
import org.apache.shiro.web.filter.AccessControlFilter;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @application:
 * @author: LiYuhang
 * @Date: 2021/7/26 11:40
 * @version: 0.1
 * @Description :
 * @Modified By:
 */
public class ShiroLoginFilter  extends AccessControlFilter {

    private final RedisUtil redisUtil;

    public ShiroLoginFilter(RedisUtil redisUtil) {
        this.redisUtil = redisUtil;
    }

    @Override
    protected boolean isAccessAllowed(ServletRequest request,ServletResponse response,Object mappedValue) throws Exception {
        return true;
    }

    @Override
    protected boolean onAccessDenied(ServletRequest request,ServletResponse response) throws Exception {
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        HttpServletResponse httpServletResponse = (HttpServletResponse) response;

        Subject subject = getSubject(httpServletRequest, httpServletResponse);
        boolean authenticated = subject.isAuthenticated();
        Date date = new Date();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //判断是否登录，如果没有登录
        if (!authenticated) {
            //如果没有登录，然后再判断是否有tokenId
            String tokenId = getTokenFromRequest(httpServletRequest);
            //如果不是PC端（第三方登录）进行tokenId鉴权操作，如果是PC端操作则放行
            if (StringUtils.isNotBlank(tokenId)&& StringUtils.isNotBlank(redisUtil.getString(tokenId))) {
                //不创建session
                request.setAttribute(DefaultSubjectContext.SESSION_CREATION_ENABLED, Boolean.FALSE);
                //执行登录
                UsernamePasswordToken token = new UsernamePasswordToken("jwt", "jwt", false);
                SecurityUtils.getSubject().login(token);
                /** 访问日志记录*/
            }
        }
        return false;
    }

    public static void clearAuth() {
        RealmSecurityManager rsm = (RealmSecurityManager) SecurityUtils.getSecurityManager();
        ShiroRealm realm = (ShiroRealm) rsm.getRealms().iterator().next();
        realm.clearAuthz();

    }

    private String getTokenFromRequest(HttpServletRequest httpRequest) {
        //从header中获取token
        String token = httpRequest.getHeader("tokenId");
        //如果header中不存在token，则从参数中获取token
        if (StringUtils.isBlank(token)) {
            return httpRequest.getParameter("tokenId");
        }
        return token;
    }
}
